package com.yzkj.cpjxc.business.service.impl;

import com.yzkj.cpjxc.business.domain.Dickm;
import com.yzkj.cpjxc.business.service.DickmService;
import com.yzkj.cpjxc.business.framework.common.BusinessMap;
import com.yzkj.cpjxc.business.framework.common.Constants;
import com.yzkj.cpjxc.business.framework.common.Pager;
import com.yzkj.cpjxc.business.framework.utils.DateTimeUtils;
import com.yzkj.cpjxc.business.framework.utils.IDUtils;
import com.yzkj.cpjxc.business.domain.SysUser;
import com.yzkj.cpjxc.business.domain.InitialFinancialBalance;
import com.yzkj.cpjxc.business.service.InitialFinancialBalanceService;
import com.yzkj.cpjxc.business.domain.PingZheng;
import com.yzkj.cpjxc.business.domain.PingZhengQueryVo;
import com.yzkj.cpjxc.business.domain.PingZhengShowVo;
import com.yzkj.cpjxc.business.service.PingZhengService;
import com.yzkj.cpjxc.business.domain.PingZhengChild;
import com.yzkj.cpjxc.business.domain.PingZhengChildShowVo;
import com.yzkj.cpjxc.business.service.PingZhengChildService;
import com.yzkj.cpjxc.business.domain.ZhangTao;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 凭证管理 Service 实现
 */
@Service
public class PingZhengServiceImpl implements PingZhengService {

	/**
	 * MyBatis 命名空间
	 */
	private final static String MAPPER_NAMESPACE = "com.chkj.xezz.pingZheng.mappers.PingZhengMapper";

	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;

	@Autowired
	private PingZhengChildService pingZhengChildService;

	@Autowired
	private DickmService dickmService;

	@Autowired
	private InitialFinancialBalanceService initialFinancialBalanceService;

	@Override
	public BusinessMap create(PingZheng pingZheng) throws Exception {
		BusinessMap bm = new BusinessMap();
		sqlSessionTemplate.insert(MAPPER_NAMESPACE + ".add", pingZheng);
		return bm;
	}

	@Override
	public boolean isExists(PingZheng pingZheng) throws Exception {
		return (Integer) sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".isExists", pingZheng) > 0;
	}

	@Override
	public PingZheng getById(String uuid) throws Exception {
		return sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getById", uuid);
	}

	@Override
	public BusinessMap edit(HttpServletRequest request, PingZheng pingZheng, ZhangTao zt, SysUser sysUser,
							String pinjiecanshu, PingZheng result) throws Exception {
		BusinessMap bm = new BusinessMap();

		// 先删除凭证
		this.deletePingZheng(result, zt);

		// 查询当前日期内最大凭证号
		PingZhengQueryVo queryVo = new PingZhengQueryVo();
		queryVo.setCompanyId(zt.getUuid());
		Map<String, Date> datemap = DateTimeUtils.getMonthEndDateForStartDate(pingZheng.getPzDate());
		queryVo.setStartTime(datemap.get(Constants.START_TIME));
		queryVo.setEndTime(pingZheng.getPzDate());

		long maxPzh = this.getMaxPzh(queryVo);
		pingZheng.setPzh((int) (maxPzh + 1));

		// 将当前月份内大于等于此凭证号的+1连号
		queryVo.setEndTime(datemap.get(Constants.END_TIME));
		queryVo.setPzh((int) (maxPzh));
		this.ziDongLianHaoUp(queryVo);

		bm = this.addPingZheng(pingZheng, pinjiecanshu, sysUser, zt);
		return bm;
	}

	@Override
	public boolean delete(String uuid) throws Exception {
		sqlSessionTemplate.delete(MAPPER_NAMESPACE + ".deleteById", uuid);
		return true;
	}

	@Override
	public Pager<PingZhengShowVo> search(Pager<PingZhengShowVo> pager, PingZhengQueryVo queryVo) throws Exception {
		List<PingZhengShowVo> dataList = sqlSessionTemplate.selectList(MAPPER_NAMESPACE + ".page", queryVo,
				new RowBounds((pager.getCurrentPage() - 1) * pager.getLimit(), pager.getLimit()));
		pager.setDataList(dataList);

		// 如果需要转换成ShowVo展示，那么就在这里转换

		Long total = sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getTotal", queryVo);
		pager.setTotal(total);
		return pager;
	}

	@Override
	public Long getMaxPzh(PingZhengQueryVo queryVo) throws Exception {
		Long maxPzh = sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getMaxPzh", queryVo);
		if (maxPzh == null) {
			return (long) 0;
		}
		return maxPzh;
	}

	@Override
	public void ziDongLianHaoDown(PingZhengQueryVo queryVo) throws Exception {
		sqlSessionTemplate.update(MAPPER_NAMESPACE + ".ziDongLianHaoDown", queryVo);
	}

	@Override
	public Long getPzCount(PingZhengQueryVo queryVo) throws Exception {
		Long pzCount = sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getPzCount", queryVo);
		if (pzCount == null) {
			return (long) 0;
		}
		return pzCount;
	}

	@Override
	public void setPzYjz(PingZhengQueryVo queryVo) throws Exception {
		sqlSessionTemplate.update(MAPPER_NAMESPACE + ".setPzYjz", queryVo);
	}

	@Override
	public Pager<PingZhengShowVo> mingXiListAjaxPage(Pager<PingZhengShowVo> pager, PingZhengQueryVo queryVo,
			List<PingZhengQueryVo> parmList) throws Exception {

		Map<String, Object> map = new HashMap<String, Object>();

		map.put("queryVo", queryVo);
		map.put("parmList", parmList);

		List<PingZhengShowVo> dataList = sqlSessionTemplate.selectList(MAPPER_NAMESPACE + ".mingXiPage", map,
				new RowBounds((pager.getCurrentPage() - 1) * pager.getLimit(), pager.getLimit()));

		for (PingZhengShowVo obj : dataList) {
			if (obj.getJfje() != null && obj.getJfje() == 0) {
				obj.setJfje(null);
			}
			if (obj.getDfje() != null && obj.getDfje() == 0) {
				obj.setDfje(null);
			}
			if (obj.getYuE() != null && obj.getYuE() == 0) {
				obj.setYuE(null);
			}
		}

		pager.setDataList(dataList);

		// 如果需要转换成ShowVo展示，那么就在这里转换

		Long total = sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".mingXiTotal", map);
		pager.setTotal(total);
		return pager;
	}

	@Override
	public void ziDongLianHaoUp(PingZhengQueryVo queryVo) throws Exception {
		sqlSessionTemplate.update(MAPPER_NAMESPACE + ".ziDongLianHaoUp", queryVo);
	}

	@Override
	public BusinessMap addPingZheng(PingZheng pingZheng, String pinjiecanshu, SysUser sysUser, ZhangTao zt)
			throws Exception {
		BusinessMap bm;
		String uuid = IDUtils.genUUID();
		Date date = new Date();
		pingZheng.setUuid(uuid);
		pingZheng.setCreateTime(date);
		pingZheng.setUpdateTime(date);
		pingZheng.setCompanyId(zt.getUuid());
		pingZheng.setZdr(sysUser.getUsername());
		pingZheng.setIsNrjz(Constants.IS_WJZ);// 是否已纳入结账0：否1：是
		bm = this.create(pingZheng);

		String[] lbs = null;
		PingZhengChild pingZhengChild = null;
		Dickm dickm = null;
		PingZhengChild maxObj = null;
		InitialFinancialBalance InitialFinancialBalance = null;
		Double qiChuValue = null;
		double increment = 0.0;
		if (bm.getIsSucc()) {
			String[] chlids = pinjiecanshu.split(",");
			for (String chlid : chlids) {
				if (StringUtils.isNotBlank(chlid)) {
					lbs = chlid.split("=");
					pingZhengChild = new PingZhengChild();
					pingZhengChild.setPzId(uuid);// 凭证ID
					pingZhengChild.setZhangTaoId(zt.getUuid());// 账套ID
					pingZhengChild.setPzDate(pingZheng.getPzDate());// 凭证日期
					pingZhengChild.setZyJl(lbs[0]);// 摘要记录
					pingZhengChild.setKmdm(lbs[1]);// 科目代码
					pingZhengChild.setKmmc(lbs[2]);// 科目名称

					if ("jfje".equals(lbs[3])) {
						pingZhengChild.setJfje(Double.parseDouble(lbs[4]));// 借方金额
					} else {
						pingZhengChild.setDfje(Double.parseDouble(lbs[4]));// 贷方金额
					}

					dickm = dickmService.getByDicCode(pingZhengChild.getKmdm());
					if (dickm != null) {
						pingZhengChild.setYueFx(dickm.getYueFx());// 余额方向 1:借 -1：贷
						pingZhengChild.setKmdmId(dickm.getUuid());// 科目ID
						// 获取当前账套中当前凭证日期内最大的凭证科目编号
						maxObj = pingZhengChildService.getMaxSequenceNumberByDate(pingZhengChild);
						if (maxObj != null) {
							pingZhengChild.setSequenceNumber(maxObj.getSequenceNumber() + 1);// 同一账套中同一科目唯一不重复编号：根据账套时间大小从1开始自增
							if ("jfje".equals(lbs[3])) {
								if ("1".equals(dickm.getYueFx())) {
									pingZhengChild.setYuE(maxObj.getYuE() + pingZhengChild.getJfje());// 当前余额
								} else {
									pingZhengChild.setYuE(maxObj.getYuE() - pingZhengChild.getJfje());// 当前余额
								}
							} else {
								if ("1".equals(dickm.getYueFx())) {
									pingZhengChild.setYuE(maxObj.getYuE() - pingZhengChild.getDfje());// 当前余额
								} else {
									pingZhengChild.setYuE(maxObj.getYuE() + pingZhengChild.getDfje());// 当前余额
								}
							}
						} else {
							pingZhengChild.setSequenceNumber(1);// 同一账套中同一科目唯一不重复编号：根据账套时间大小从1开始自增

							InitialFinancialBalance = initialFinancialBalanceService
									.getByZhangTaoIdAndKeMuId(zt.getUuid(), dickm.getUuid());
							if (InitialFinancialBalance != null) {

								qiChuValue = InitialFinancialBalance.getQiChuValue();
								if (qiChuValue == null) {
									qiChuValue = 0.0;
								}

								if ("jfje".equals(lbs[3])) {
									if ("1".equals(dickm.getYueFx())) {
										pingZhengChild.setYuE(qiChuValue + pingZhengChild.getJfje());// 当前余额
									} else {
										pingZhengChild.setYuE(qiChuValue - pingZhengChild.getJfje());// 当前余额
									}
								} else {
									if ("1".equals(dickm.getYueFx())) {
										pingZhengChild.setYuE(qiChuValue - pingZhengChild.getDfje());// 当前余额
									} else {
										pingZhengChild.setYuE(qiChuValue + pingZhengChild.getDfje());// 当前余额
									}
								}
							} else {
								if ("jfje".equals(lbs[3])) {
									if ("1".equals(dickm.getYueFx())) {
										pingZhengChild.setYuE(pingZhengChild.getJfje());// 当前余额
									} else {
										pingZhengChild.setYuE(pingZhengChild.getJfje() * (-1));// 当前余额
									}
								} else {
									if ("1".equals(dickm.getYueFx())) {
										pingZhengChild.setYuE(pingZhengChild.getDfje() * (-1));// 当前余额
									} else {
										pingZhengChild.setYuE(pingZhengChild.getDfje());// 当前余额
									}
								}
							}
						}

						if ("jfje".equals(lbs[3])) {
							if ("1".equals(dickm.getYueFx())) {
								increment = pingZhengChild.getJfje();
							} else {
								increment = pingZhengChild.getJfje() * (-1);
							}
						} else {
							if ("1".equals(dickm.getYueFx())) {
								increment = pingZhengChild.getDfje() * (-1);
							} else {
								increment = pingZhengChild.getDfje();
							}
						}

						// 修改大于等于当前科目编号的科目编号自增1,并且自动修改其余额
						pingZhengChildService.updateMaxDataToUp(pingZhengChild, increment);
						// 新增
						pingZhengChildService.create(pingZhengChild);
					}
				}
			}
		}
		return bm;
	}

	@Override
	public boolean deletePingZheng(PingZheng result, ZhangTao zt) throws Exception {
		// 删除凭证主表
		boolean flag = this.delete(result.getUuid());

		if (flag) {
			// 主表自动连号(删除月份凭证号重新连号)
			Map<String, Date> datemap = DateTimeUtils.getMonthEndDateForStartDate(result.getPzDate());
			PingZhengQueryVo queryVo = new PingZhengQueryVo();
			queryVo.setCompanyId(zt.getUuid());
			queryVo.setStartTime(datemap.get(Constants.START_TIME));
			queryVo.setEndTime(datemap.get(Constants.END_TIME));
			queryVo.setPzh(result.getPzh());
			this.ziDongLianHaoDown(queryVo);

			// 删除关联子表
			this.deleteChildPingZheng(result.getUuid());
		}
		
		return flag;
	}
	
	@Override
	public void deleteChildPingZheng(String pingZhengId) throws Exception {
		//同时假删关联子表
		List<PingZhengChildShowVo> pcList = pingZhengChildService.getBypzid(pingZhengId);
		double increment = 0.0;
		for (PingZhengChildShowVo vo : pcList) {

			if (vo.getJfje() != null) {
				if ("1".equals(vo.getYueFx())) {
					increment = vo.getJfje();
				} else {
					increment = vo.getJfje() * (-1);
				}
			} else {
				if ("1".equals(vo.getYueFx())) {
					increment = vo.getDfje() * (-1);
				} else {
					increment = vo.getDfje();
				}
			}
			//删除数据
			pingZhengChildService.delete(vo.getUuid());
			//修改大于当前科目编号的科目编号自减1,并且自动修改其余额
			pingZhengChildService.updateMaxDataToDown(vo, increment);
		}
	}


}
